package com.recource.interceptor;

import com.recource.annonation.Login;
import com.recource.domain.Users;
import com.recource.util.HostHolder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yujie
 * @createTime 2023/1/5 15:25
 * @description
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private HostHolder hostHolder;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod)handler;
            Class<?> clazz = handlerMethod.getBeanType();
            //检查调用的方法是否有login注解
            if(clazz.isAnnotationPresent(Login.class) || handlerMethod.getMethod().isAnnotationPresent(Login.class)){
                //检查当前页面是否需要登录信息，如果没有登录跳转回登录页面
                if(Objects.isNull(request.getCookies())){
                    response.sendRedirect(request.getContextPath()+"/login.html");
                    return false;
                }
                List<Cookie> cookies = Arrays.asList(request.getCookies());
                List<String> cookieNames = cookies.stream().map(Cookie::getName).collect(Collectors.toList());
                //检查cookie请求头内是否有token登录信息
                if(!CollectionUtils.contains( cookieNames.iterator(), "token")){
                    //如果没有登录信息返回登录界面
                    response.sendRedirect(request.getContextPath()+"/login.html");
                    return false;
                }
                Map<String, String> map = new HashMap<>();
                cookies.forEach(cookie -> {
                    map.put(cookie.getName(), cookie.getValue());
                });
                //获取登录信息session
                String sessionId = map.get("token");
                if(StringUtils.isEmpty(sessionId)){
                    response.sendRedirect(request.getContextPath()+"/login.html");
                    return false;
                }
                //获取存在服务器内的session获取当前用户的信息
                Object attribute = request.getSession().getAttribute(sessionId);
                // 获取用户信息
                if(Objects.nonNull(attribute) && attribute instanceof Users){
                    Users users = (Users) attribute;
                    hostHolder.setUser(users);
                    return true;
                }else{
                    //如果cookie中保持的用户信息已经失效就跳转回登录页面
                    response.sendRedirect(request.getContextPath()+"/login.html");
                    return false;
                }
            }else{
                //TODO 不需要登录的修改
                Map<String, String> map = new HashMap<>();
                Cookie[] cookies = request.getCookies();
                if(Objects.nonNull(cookies)){
                    for (Cookie cookie : cookies) {
                        map.put(cookie.getName(), cookie.getValue());
                    }
                    String token = map.get("token");
                    if(StringUtils.isNotEmpty(token)){
                        Object attribute = request.getSession().getAttribute(token);
                        //校验参数
                        if(Objects.nonNull(attribute) && attribute instanceof Users){
                            Users users = (Users) attribute;
                            //向当前请求线程注入user用户信息
                            hostHolder.setUser(users);
                        }
                    }
                }
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        Users users = hostHolder.getUser();
        if(users != null && modelAndView != null){
            //在视图层渲染用户信息
            modelAndView.addObject("loginUser", users);
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清除用户信息
        hostHolder.clear();
    }
}
